package com.finger.gulimall.product.service.impl;

import com.finger.common.constant.ProductConstant;
import com.finger.common.utils.Constant;
import com.finger.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.finger.gulimall.product.entity.AttrGroupEntity;
import com.finger.gulimall.product.entity.CategoryEntity;
import com.finger.gulimall.product.service.AttrAttrgroupRelationService;
import com.finger.gulimall.product.service.AttrGroupService;
import com.finger.gulimall.product.service.CategoryService;
import com.finger.gulimall.product.vo.AttrRespVO;
import com.finger.gulimall.product.vo.AttrVO;
import com.finger.gulimall.product.vo.BaseAttrs;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.finger.common.utils.PageUtils;
import com.finger.common.utils.Query;

import com.finger.gulimall.product.dao.AttrDao;
import com.finger.gulimall.product.entity.AttrEntity;
import com.finger.gulimall.product.service.AttrService;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    private AttrAttrgroupRelationService relationService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private AttrGroupService groupService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void saveAttr(AttrVO attr) {
        // 保存属性实体
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr, attrEntity);
        baseMapper.insert(attrEntity);

        // 如果是基本属性类型，就保存 属性 和属性分组中间表的关系
        if (ProductConstant.AttrEnume.ATTR_TYPE_BASE.getCode() == attr.getAttrType() || ProductConstant.AttrEnume.ATTR_TYPE_DOUBLE.getCode() == attr.getAttrType()) {
            //保存属性分组关系实体
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrId(attrEntity.getAttrId());
            relationEntity.setAttrSort(0);
            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            relationService.save(relationEntity);
        }

    }

    @Transactional
    @Override
    public void updateDetails(AttrVO attr) {
        // 创建实体
        AttrEntity attrEntity = new AttrEntity();
        // 复制属性
        BeanUtils.copyProperties(attr, attrEntity);
        // 更新属性表中的数据
        baseMapper.updateById(attrEntity);
        Integer attrType = attr.getAttrType();
        // 如果更新的是基本属性中的数据，则级联更新属性和属性分组中间表中的数据
        if (ProductConstant.AttrEnume.ATTR_TYPE_BASE.getCode() == attrType || ProductConstant.AttrEnume.ATTR_TYPE_DOUBLE.getCode() == attrType) {
            // 级联更新属性和属性分组中间表中的数据
            relationService.updateRelationDetails(attr.getAttrId(), attr.getAttrGroupId());
        }
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params, Integer catId, String type) {
        // 查询条件
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<>();

        // 前端传过来的id不为空
        if (catId != 0) {
            wrapper.eq("catelog_id", catId);
        }

        // 前端传过来进行模糊查询的名字
        String key = (String) params.get("key");


        // 根据分类Id查询或者是根据属性名做模糊查询
        if (!StringUtils.isEmpty(key)) {
            wrapper.and(w -> {
                w.eq("catelog_id", catId).or().like("attr_name", key);
            });
        }

        if (ProductConstant.AttrEnume.ATTR_TYPE_BASE.getMsg().equalsIgnoreCase(type)) {
            wrapper.eq("attr_type", ProductConstant.AttrEnume.ATTR_TYPE_BASE.getCode()).or().eq("attr_type", ProductConstant.AttrEnume.ATTR_TYPE_DOUBLE.getCode());
        } else {
            wrapper.eq("attr_type", ProductConstant.AttrEnume.ATTR_TYPE_SALE.getCode()).or().eq("attr_type", ProductConstant.AttrEnume.ATTR_TYPE_DOUBLE.getCode());
        }

        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                wrapper
        );

        List<AttrRespVO> respVOs = page.getRecords().stream().map(item -> {
            // 响应实体类创建
            AttrRespVO attrRespVO = new AttrRespVO();
            // 复制属性
            BeanUtils.copyProperties(item, attrRespVO);
            // 获取分类的全部路径Id值[父/子/孙]，用于前端表单回显
            CategoryEntity category = categoryService.getById(item.getCatelogId());
            // 设置分类的全部路径Id值
            attrRespVO.setCatelogName(category.getName());
            // 属性id
            Long attrId = item.getAttrId();

            // 如果 type 为 base，则说明是基本属性，那就从数据库查对应的属性分组名
            if (ProductConstant.AttrEnume.ATTR_TYPE_BASE.getMsg().equalsIgnoreCase(type)) {
                // 根据属性id从属性和属性分组关联表中查取数据
                AttrAttrgroupRelationEntity relationEntity = relationService.getOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
                if (relationEntity != null) {
                    // 获取属性分组Id
                    Long attrGroupId = relationEntity.getAttrGroupId();
                    // 属性可能没有添加分组
                    if (attrGroupId != null) {
                        // 根据属性分组ID查属性分组
                        AttrGroupEntity groupEntity = groupService.getById(attrGroupId);
                        // 响应VO设置分组名
                        attrRespVO.setGroupName(groupEntity.getAttrGroupName());
                    }
                }
            }

            // 返回
            return attrRespVO;
            // 收集成集合
        }).collect(Collectors.toList());

        PageUtils page2 = new PageUtils(respVOs, (int) page.getTotal(), (int) page.getPages(), (int) page.getCurrent());
        return page2;

    }

    // 当删除属性时，级联删除属性和属性分组中间表中的数据
    @Transactional
    @Override
    public void removeCascadeDetails(List<Long> asList) {
        int i = baseMapper.deleteBatchIds(asList);
        if (i != 0) {
            // 遍历级联删除属性和属性分组中间表中的数据
            asList.forEach(id -> {
                QueryWrapper<AttrAttrgroupRelationEntity> wrapper = new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", id);
                relationService.remove(wrapper);
            });
        }
    }


    @Override
    public List<Long> getSearchAttrIds(List<Long> productAttrIds) {

        List<Long> searchAttrIds = baseMapper.getSearchAttrIds(productAttrIds);
        return searchAttrIds;
    }

    @Cacheable(value = "attr", key = "'attrId:'+#root.args[0]")
    @Override
    public String getAttrNameByAttrId(Long attrId) {
        AttrEntity attrEntity = baseMapper.selectById(attrId);
        return attrEntity.getAttrName();
    }

    @Override
    public AttrRespVO getDetails(Long attrId) {
        // 根据属性Id查出属性实体
        AttrEntity attrEntity = baseMapper.selectById(attrId);
        // 创建一个用于表单回显的属性VO类
        AttrRespVO attrRespVO = new AttrRespVO();
        // 复制属性
        BeanUtils.copyProperties(attrEntity, attrRespVO);
        // 获取该属性在哪个分类菜单下的绝对路径【父/子/孙】
        Long[] paths = categoryService.getPaths(attrRespVO.getCatelogId());
        attrRespVO.setCatelogPath(paths);

        // 如果查询的是 基本属性，就借着从数据库查询 分组Id
        if (ProductConstant.AttrEnume.ATTR_TYPE_BASE.getCode() == attrEntity.getAttrType()) {
            // 准备查询条件，在属性和属性分类表中查询出属性分组Id
            QueryWrapper<AttrAttrgroupRelationEntity> queryWrapper = new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId()).select("attr_group_id");
            // 执行查询
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = relationService.getOne(queryWrapper);

            if (attrAttrgroupRelationEntity != null) {
                // 提取属性分组Id
                Long attrGroupId = attrAttrgroupRelationEntity.getAttrGroupId();
                // 设置属性分组Id
                attrRespVO.setAttrGroupId(attrGroupId);
            }
        }
        // 返回
        return attrRespVO;
    }

}